package main

import (
	"fmt"
	"os"
	"os/exec"
)

// underlyingError 会返回已知的操作系统相关错误的潜在错误值。
func underlyingError(err error) error {
	switch err := err.(type) {
	case *os.PathError:
		return err.Err
	case *os.LinkError:
		return err.Err
	case *os.SyscallError:
		return err.Err
	case *exec.Error:
		return err.Err
	}
	return err
}

func main() {
	r, w, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "unexpected error: %s\n", err)
		return
	}
	// 人为制造 *os.PathError 类型的错误。
	r.Close()
	_, err = w.Write([]byte("hi"))
	if err != nil {
		uError := underlyingError(err)
		fmt.Fprintf(os.Stderr, "underlying error: %s (type: %T)\n", uError, uError)
	}
}